// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


#ifndef CPH_MEDIA_ENGINE_H
#define CPH_MEDIA_ENGINE_H

#include <cstdint>

//视频时延统计扩展参数
struct VideoLatencyExt {
    uint64_t startCaptureTimestamp;
    uint64_t endCaptureTimestamp;
    uint64_t startEncodeTimestamp;
    uint64_t endEncodeTimestamp;
};

//视频扩展回调参数
struct VideoCallbackExt {
    uint64_t timestamp;     //当前帧的时间戳
    uint8_t orientation;
    VideoLatencyExt videoLatencyExt;
    uint32_t refreshRate;
};

//音频扩展回调参数
struct AudioCallbackExt {
    uint8_t channels = 2;                   // 声道数 1：MONO/2:STEREO(默认)
    uint8_t audioBitDepth = 16;             // 采样深度 8bit/16bit(默认)
    uint32_t sampleRate = 48000;            // 采样率 44100Hz/48000Hz(默认)，只有在OPUS格式有效
    uint32_t sampleInterval = 10;           // 采样间隔 10ms(默认)/20ms，只有在OPUS格式有效
    uint64_t timestamp;                     // 音频数据时间戳 微秒，UTC时间
};

// 仿真硬件状态
enum VmiDeviceStatus {
    VMI_INVALID,
    VMI_INIT,
    VMI_ENABLED,
    VMI_DISABLED
};

// 仿真硬件类型
enum VmiDeviceType {
    CAMERA,
    MICROPHONE,
    SENSOR,
    DEVICE_MAX
};

// 仿真硬件支持的数据类型
enum DataType {
    VMI_H264,
    VMI_JPEG,
    VMI_I420,
    VMI_PCM,
    VMI_OPUS
};

// 仿真硬件初始化配置
struct VmiConfigParams {
    DataType dataType = VMI_H264;
    uint32_t reserved1 = 0;
    uint32_t reserved2 = 0;
    uint32_t reserved3 = 0;
};

// 仿真硬件扩展回调参数
struct VmiDeviceCallbackExt {
    uint64_t timestamp = 0;
    VmiDeviceType dataType = CAMERA;
    uint32_t reserved1 = 0;
    uint32_t reserved2 = 0;
    uint32_t reserved3 = 0;
};

// 触控数据结构体
struct InputTouch {
    uint8_t pointerID;
    uint8_t orientation;
    uint8_t action;
    uint16_t pressure;
    uint16_t touchX;
    uint16_t touchY;
    uint16_t physicalWidth;
    uint16_t physicalHeight;
    int32_t touchTime;
    uint8_t reserved[16];
};

// 键值数据结构体
struct InputKey {
    uint16_t keyCode;
    uint16_t action;
    uint8_t reserved[8];
};

/**
 * @功能描述：视频数据回调函数
 * @参数：   uint8_t* 数据
 *          uint32_t 数据长度
 *          VideoCallbackExt 扩展回调参数
 */
using  VideoCallback = void(*)(uint8_t*, uint32_t, VideoCallbackExt&);

/**
 * @功能描述：音频数据回调函数
 * @参数：   uint8_t* 数据
 *          uint32_t 数据长度
 *          AudioCallbackExt 扩展回调参数
 */
using AudioCallback = void(*)(uint8_t *, uint32_t, AudioCallbackExt&);

/**
 * @功能描述：硬件仿真数据回调函数
 * @参数：   uint8_t* 数据
 *          uint32_t 数据长度
 *          VmiDeviceCallback 扩展回调参数
 */
using VmiDeviceCallback = void(*)(uint8_t *, uint32_t, VmiDeviceCallbackExt&);

class CPHMediaEngine {
public:
    /**
     * @功能描述：构造函数
     */
    CPHMediaEngine();

    /**
     * @功能描述：析构函数
     */
    ~CPHMediaEngine();

    /**
     * @功能描述：版本号获取
     * @返回值：版本号
     */
    const char* GetVersion();

    /**
     * @功能描述：获取媒体服务支持能力
     * @返回值：云手机支持能力json串
     */
    const char* GetCPHMediaFeatures();

    /**
     * @功能描述：视频初始化及启动
     * @参数：	jsonConfig     json格式的视频配置参数
                VideoCallback  视频回调函数
     * @返回值：0成功 -1失败
     */
    int OpenVideo(const char* jsonConfig, VideoCallback callback);

    /**
     * @功能描述：视频停止并销毁
     * @返回值：0成功 -1失败
     */
    int CloseVideo();

    /**
     * @功能描述：视频参数设置,json字符串，只需要提供需要修改的字段
     * @返回值：0成功 -1失败
     */
    int SetParams(const char* jsonConfig);

    /**
    * @功能描述：物理分辨率参数设置
    * @参数：width目标宽度，height目标高度
    * @返回值：0成功 -1失败
    */
    int SetPhysicalResolution(int width, int height);

    /**
     * @功能描述：强制产生I帧
     * @返回值：0成功 -1失败
     */
    int GenerateKeyFrame();

    /**
     * @功能描述：使用json配置参数启动音频服务，获取音频数据
     * @参数 [in]：const char* jsonConfig: json格式音频初始化参数
				   AudioCallback callback: 音频数据回调函数
     * @返回值：0成功，-1启动音频服务失败
     */
    int OpenAudio(const char* jsonConfig, AudioCallback callback);

    /**
    * @功能描述：结束音频服务
    * @返回值：0成功 -1销毁音频服务失败
    */
    int CloseAudio();

    /**
    * @功能描述：注入触控数据
    * @参数 [in] inputTouch：触控数据结构体
    * @返回值：0成功，小于0数据处理失败
    */
    int InjectTouchData(const InputTouch &inputTouch);

    /**
     * @功能描述：注入按键数据
     * @参数 [in] inputKey：键值数据结构体
     * @返回值：0成功，小于0数据处理失败
     */
    int InjectKeyData(const InputKey &inputKey);

    /**
     * @功能描述：服务端接收手柄操控数据处理(有客户端配套)
     * @参数 [in] buf:接收的操控数据的内存指针
     * @参数 [in] length:接收的操控数据长度
     * @返回值：0成功，-1数据处理失败
     */
    int InjectAxisData(void *buf, unsigned long length);

    /**
     * @功能描述: 通过仿真硬件类型和初始化参数，初始化仿真硬件
     * @参数[in]: VmiDeviceType deviceType: 仿真硬件类型
     *           VmiConfigParams& params: 仿真硬件初始化参数
     *           VmiDeviceCallback callback: 仿真硬件回调函数
     * @返回值:  0: 成功;
     *         -1: 仿真硬件初始化失败;
     */
    int InitVmiDevice(VmiDeviceType deviceType, VmiConfigParams& params, VmiDeviceCallback callback);

    /**
     * @功能描述: 通过仿真硬件类型使能对应仿真硬件
     * @参数[in]: VmiDeviceType deviceType: 仿真硬件类型
     * @返回值:  0: 成功;
     *         -1: 仿真硬件使能失败;
     */
    int EnableVmiDevice(VmiDeviceType deviceType);

    /**
     * @功能描述: 通过仿真硬件类型禁用对应仿真硬件
     * @参数[in]: VmiDeviceType deviceType: 仿真硬件类型
     * @返回值:  0: 成功;
     *         -1: 仿真硬件禁用失败;
     */
    int DisableVmiDevice(VmiDeviceType deviceType);

    /*
     * @功能描述: 通过仿真硬件类型销毁对应仿真硬件
     * @参数[in]: VmiDeviceType deviceType: 仿真硬件类型
     * @返回值:  0: 成功
     *         -1: 仿真硬件销毁失败
     */
    int DestroyVmiDevice(VmiDeviceType deviceType);

    /*
     * @功能描述: 数据注入到仿真硬件
     * @参数[in]: VmiDeviceType deviceType: 仿真硬件类型
     *            uint8_t* data；注入的数据
     *            uint32_t len：数据长度
     * @返回值:  0: 成功
     *         -1: 仿真硬件数据注入失败
     */
    int VmiDeviceSend(VmiDeviceType deviceType, uint8_t* data, uint32_t len);

    /*
     * @功能描述: 通过仿真硬件类型获取对应仿真硬件状态
     * @参数[in]: VmiDeviceType deviceType: 仿真硬件类型
     * @返回值: VMI_INVALID 无效
     *         VMI_INIT 初始化
     *         VMI_ENABLED 使能
     *         VMI_DISABLED 禁止
     */
    VmiDeviceStatus GetVmiDeviceStatus(VmiDeviceType deviceType);
};

#endif